#include "player.proj.hpp"
#include "player.impl.hpp"
#include "stdexcept"
#include "PlayerNative.h"
#include "taihe/napi_runtime.hpp" 
#include "AVCodecSampleLog.h"
#include <string>
#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0xFF00
#define LOG_TAG "player"

namespace {
// To be implemented.

void Callback(void *callbackData) {
    auto* cbPtr = reinterpret_cast<::taihe::callback<void()>*>(callbackData);
    if (cbPtr == nullptr) {
        AVCODEC_SAMPLE_LOGE("Invalid callback data (nullptr)");
        return;
    }

    // 获取当前环境和UV事件循环
    napi_env env = ::taihe::get_env();
    uv_loop_s* loop = nullptr;
    napi_get_uv_event_loop(env, &loop);

    // 封装回调数据，通过UV工作队列调度到主线程
    uv_work_t* work = new uv_work_t;
    work->data = cbPtr;  // 传递回调指针

    uv_queue_work(
        loop,
        work,
        [](uv_work_t* work) {
            // 工作线程不执行实际操作（仅用于调度）
        },
        [](uv_work_t* work, int status) {
            // 此回调在JS主线程执行
            auto* cbPtr = reinterpret_cast<::taihe::callback<void()>*>(work->data);
            if (cbPtr != nullptr) {
                (*cbPtr)();  // 安全调用JS回调
                delete cbPtr;  // 释放堆内存
            }
            delete work;
        }
    );
}


void playNative(int32_t inputFileFd, int64_t inputFileOffset, int64_t inputFileSize, ::taihe::callback_view<void()> cbFn) {
    SampleInfo sampleInfo;
    size_t argc = 4;

    sampleInfo.inputFd=inputFileFd;
    sampleInfo.inputFileOffset=inputFileOffset;
    sampleInfo.inputFileSize=inputFileSize;

    sampleInfo.playDoneCallback = &Callback;
     ::taihe::callback<void()> *cb = new ::taihe::callback<void()>(cbFn);
    sampleInfo.playDoneCallbackData = cb;

    int32_t ret = Player::GetInstance().Init(sampleInfo);
    
    if (ret == AVCODEC_SAMPLE_ERR_OK) {
        
        Player::GetInstance().Start();
    }
}
}  // namespace

// Since these macros are auto-generate, lint will cause false positive.
// NOLINTBEGIN
TH_EXPORT_CPP_API_playNative(playNative);
// NOLINTEND

